/**
 * 歌词滚动
 * author: lanqin
 * zhenjiang.szj@alibaba-inc.com
 * since 2016.05.30
 * modified by yueshui at 2017.3.6
 */

class LyricView {

  constructor (container, dataStr) {
    container = container || document.body;
    this.con = container;
    this.line = 0;
    this.showData = {};
    this.formatShowData = {};
    this.hasLyric = false;
    if(dataStr){
      this.parseData(dataStr);
      this.render(container, this.formatShowData);
      this.reset();
    }
  }

  /**
  * 解析 lrc 字符串
  */
  parseData (dataStr) {
    let dataArr = dataStr.split('\n');
    for (let i = 0, len = dataArr.length; i < len; i ++) {
      let lrcClause = dataArr[i].replace(/\[\d*:\d*((\.|\:)\d*)*\]/g, '');
      let timeArr = dataArr[i].match(/\[\d*:\d*((\.|\:)\d*)*\]/g);
      if (timeArr) {
        for (let j = 0, lenn = timeArr.length; j < lenn; j++) {
          let min = Math.floor(timeArr[j].match(/\[\d*/i).toString().slice(1));
          let sec = Math.floor(timeArr[j].match(/\:\d*/i).toString().slice(1));
          let time = min * 60 + sec;
          this.showData[time] = lrcClause.replace(/(^\s*)|(\s*$)/g, '');
        }
      }
    }
    for (let index in this.showData) {
      if (this.showData[index] != '' && index != '0') {
        this.formatShowData[index] = this.showData[index];
      }
    }
  }

  /**
  * 渲染歌词区域
  */
  render (con, data) {
    let i = 0;
    let html = [];
    let indexArr = [];

    // blitz 内核需要对键值先进行排序，chrome不需要
    function sortNumber(a, b) {
      return a - b;
    }
    for (let index in data) {
      indexArr.push(index);
    }
    indexArr.sort(sortNumber);
    this.indexArr = indexArr;
    let len = indexArr.length;
    if(len != 0){
      this.hasLyric = true;
      this.lastLine = -2;
    }
    let j = 0;
    for (i = 0; i < len; i++) {
      let index = indexArr[j];
      let lrcClause = data[index];
      // 处理英文歌词
      if (escape(lrcClause).indexOf("%u")<0) { 
        // 处理英文换行
        if (lrcClause.length > 40) {
          let tempArr = lrcClause.split(' ');
          let len = tempArr.length;
          let clause1 = tempArr.slice(0, len / 2).join(' ');
          let clause2 = tempArr.slice(len / 2, len).join(' ');
          html[j] = `<p class="song-clause" id="song-line${j}">${clause1}</p>`;
          html[j + 1] = `<p class="song-clause" id="song-line${j+1}">${clause2}</p>`;
          let nextIndex = indexArr[j+1] || index;
          let insertIndex = (+index + (+nextIndex)) / 2;
          indexArr.splice(j+1, 0, +insertIndex); // 插入一行, 播放时间点为insertIndex
          j += 2;        
        } else {
          html[j] = `<p class="song-clause" id="song-line${j}">${lrcClause}</p>`;
          j++;
        }
      } else { // 处理非英文歌词
        // 中文换行 
        if (lrcClause.length > 20) {
          let len = lrcClause.length;
          let clause1 = lrcClause.slice(0, len/2);
          let clause2 = lrcClause.slice(len/2, len);

          html[j] = `<p class="song-clause" id="song-line${j}">${clause1}</p>`;
          html[j + 1] = `<p class="song-clause" id="song-line${j+1}">${clause2}</p>`;
          let nextIndex = indexArr[j+1] || index;
          let insertIndex = (+index + (+nextIndex)) / 2;
          indexArr.splice(j+1, 0, +insertIndex); // 插入一行, 播放时间点为insertIndex
          j += 2;
        } else {
          html[j] = `<p class="song-clause" id="song-line${j}">${lrcClause}</p>`;
          j++;
        }
      }
    }
    this.line = j;
    let lrcHtml = (html.join(' '));
    con.innerHTML = `<div class="lrc-container">${lrcHtml}</div>`;
    this.calculate();
  }

  calculate(){
    this.wrapHeight = this.con.clientHeight;
    var line = document.querySelector('#song-line0');
    this.lineHeight = line.offsetHeight;
    var visibleLines = this.wrapHeight / this.lineHeight;
    this.scrollLines = Math.floor(visibleLines / 2);
  }

  updateNoLyric(msg){
    this.hasLyric = false;
    var marginTop = this.con.clientHeight / 2 - 30;
    this.con.innerHTML = `<div class="lrc-container"><p class='song-clause' id='song-line0' style='margin-top: ${marginTop}px'>${msg}</p></div>`;
  }

  /**
  * 刷新歌词内容
  */
  refresh (dataStr) {
    this.line = 0;
    this.showData = {};
    this.formatShowData = {};
    this.parseData(dataStr);
    this.render(this.con, this.formatShowData);
    this.reset();
  }

  reset () {
    // 初始时偏移量需要确定
    document.querySelector('.lrc-container').transform = 'translateY(0px)';
  }

  scrollLrc (time) {
    if(!this.hasLyric){
      return;
    }
    let curTime = Math.round(time);
    let start = false;
    let i = 0;
    //console.log('---------------this.indexArr------: ' + JSON.stringify(this.indexArr));
    let len = this.indexArr.length;
    for (i = 0; i < len; i++) {
      let index = this.indexArr[i];
      if (index < curTime) {
        start = true;
      } else {
        break;
      }
    }
    let cLine = document.querySelector('#song-line' + (i - 1));
    if (cLine && start) {
      cLine.classList.add('current-line');
      // 处理一行拆成两行的情况，如果间隔为0.5秒，两行都变色，防止拆分出的第二行不变色
      if (+this.indexArr[i+1] == +this.indexArr[i] + 0.5) {
        let nLine = document.querySelector('#song-line' + i);
        console.log('nline: ' + nLine.innerHTML);
        nLine && nLine.classList.add('current-line');
        this.scrollLrcLine(i - 1, true);
      } else {
        this.scrollLrcLine(i - 1);
      }      
    }
  }

  scrollLrcLine (lineNum, nohide) {
    //let stride = 75; // 歌词滚动距离
    if(this.lastLine == lineNum){
      return;
    }
    this.lastLine = lineNum;
    let preline;
    lineNum = parseInt(lineNum);
    let moveBox = document.querySelector('.lrc-container');

    try {
      if (lineNum > 0) {
        preline = lineNum - 1;
      } else {
        preline = this.line - 1;
      }
      let newy = -(lineNum - this.scrollLines) * this.lineHeight;
      if (newy > 0) newy = 0;
      let ccLine = null;
      if (preline - 1 > 0)
        ccLine = document.querySelector('#song-line' + (preline - 1));
      let cLine = document.querySelector('#song-line' + preline);
      let nLine = document.querySelector('#song-line' + (lineNum + 1));
      if (ccLine) {
        ccLine.classList.remove('current-line');
      }
      if (cLine) {
        cLine.classList.remove('current-line');
      }
      if (nLine && !nohide) {
        nLine.classList.remove('current-line');
      }
      moveBox.style.transform = `translateY(${newy}px)`;
    } catch (err) {
      console.log(err);
    }
  }
}

module.exports = LyricView;
